import requests
from urllib.parse import urlencode

import deezer.utils
import deezer.track
import deezer.artist
import deezer.album

class Deezer:
  def __init__(self):
    self.session = requests.Session()
    self.http_headers = {
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
      "Content-Language": "en-US",
      "Cache-Control": "max-age=0",
      "Accept": "*/*",
      "Accept-Charset": "utf-8,ISO-8859-1;q=0.7,*;q=0.3",
      "Accept-Language": "en-US,en;q=0.9,en-US;q=0.8,en;q=0.7",
      "Connection": 'keep-alive'
    }
    self.user = None

  def call_private_api(self, method, args = {}):
    query_string = {
      "api_version": "1.0",
      "api_token": "null",
      "input": "3",
      "method": method
    }

    if method != "deezer.getUserData":
      query_string["api_token"] = self.get_api_token()

    return self.session.post(
      deezer.utils.PRIVATE_API_URL % urlencode(query_string),
      data = args,
      headers = self.http_headers
    ).json()

  def get_api_token(self):
    json = self.call_private_api("deezer.getUserData")
    if "checkFormLogin" in json["results"]:
      return json["results"]["checkFormLogin"]
    elif "checkForm" in json["results"]:
      return json["results"]["checkForm"]
    else:
      raise "couldn't get api_token"

  def login(self, mail, password):
    login_token = self.get_api_token()

    json = {
      "type": "login",
      "mail": mail,
      "password": password,
      "checkFormLogin": login_token,
      "reCaptchaToken": "",
      "reCaptchaDisabled": 1
    }
    headers = {
      **self.http_headers,
      "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
    }

    result = self.session.post(
      'https://www.deezer.com//ajax/action.php?',
      data = json,
      headers = headers,
    )
    if result.text != "success":
      raise 'wrong email or password'

    result = self.session.get("https://www.deezer.com/", headers=headers)
    if result.status_code != 200:
      raise "couldn't load deezer.com"

    result = self.call_private_api('deezer.getUserData')
    user_data = result["results"]["USER"]
    self.user = {
      "email": mail,
      "id": user_data["USER_ID"],
      "name": user_data["BLOG_NAME"],
    }
    if "USER_PICTURE" in user_data:
      self.user["picture_url"] = deezer.utils.USER_PICTURES_URL % user_data["USER_PICTURE"]
    return self.user

  def get_track_data(self, track_id):
    if track_id < 0:
      return self.call_private_api(
        'song.getData',
        args = '{"SNG_ID": %i}' % track_id
      )
    else:
      return self.call_private_api(
        'deezer.pageTrack',
        args = '{"SNG_ID": %i}' % track_id
      )
  def get_track(self, track_id):
    return deezer.track.DeezerTrack.grab_or_create(
      track_id,
      raw_data = self.get_track_data(track_id)["results"]["DATA"]
    )

  def get_artist_data(self, artist_id):
    return self.call_private_api(
      'deezer.pageArtist',
      args = '{"ART_ID": %i, "LANG": "EN"}' % artist_id
    )
  def get_artist(self, artist_id):
    return deezer.artist.DeezerArtist.grab_or_create(
      artist_id,
      raw_data = self.get_artist_data(artist_id)["results"]
    )

  def get_album_data(self, album_id):
    return self.call_private_api(
      'deezer.pageAlbum',
      args = '{"ALB_ID": %i, "LANG": "EN"}' % album_id
    )
  def get_album(self, album_id):
    return deezer.album.DeezerAlbum.grab_or_create(
      album_id,
      raw_data = self.get_album_data(album_id)["results"]
    )

